package com.smile.cn.bean;

import com.smile.cn.entity.EMail;
import com.smile.cn.entity.MailAuthentication;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.pop3.POP3Folder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.search.AndTerm;
import javax.mail.search.BodyTerm;
import javax.mail.search.FromStringTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SentDateTerm;
import javax.mail.search.SizeTerm;
import javax.mail.search.SubjectTerm;

public class ReceiveEmailBean {
	private MailAuthentication account = null;
	private Folder allFolder = null;
	private String mailType = null;
	private String imap = "imap";
	private String pop3 = "pop3";
	private String pop = "pop";

	public ReceiveEmailBean(MailAuthentication _account) throws Exception {
		this.account = _account;
	}

	public List<EMail> getFactorEmails(String isRead, String addresser,
			String subject, String body, int mailSize1, int mailSize2,
			Date date1, Date date2) throws Exception {
		IMAPFolder imapFolder = null;
		POP3Folder pop3Folder = null;
		Message[] msgs = (Message[]) null;
		SearchTerm search = null;
		List<Object> factorList = new ArrayList<Object>();
		List<EMail> mails = new ArrayList<EMail>();
		if (addresser != null)
			factorList.add(new FromStringTerm(addresser));
		else if (subject != null)
			factorList.add(new SubjectTerm(subject));
		else if (body != null)
			factorList.add(new BodyTerm(body));
		else if (mailSize1 > 0)
			factorList.add(new SizeTerm(6, mailSize1));
		else if (mailSize2 > 0)
			factorList.add(new SizeTerm(1, mailSize2));
		else if (date1 != null)
			factorList.add(new SentDateTerm(6, date1));
		else if (date2 != null) {
			factorList.add(new SentDateTerm(1, date2));
		}
		SearchTerm[] s = new SearchTerm[factorList.size()];
		for (int i = 0; i < s.length; i++) {
			s[i] = ((SearchTerm) factorList.get(i));
		}
		if (s.length == 0) {
			return getAllEMails();
		}
		search = new AndTerm(s);
		try {
			GetFolderBean getFolder = new GetFolderBean();
			this.allFolder = getFolder.getFolder(this.account);
			this.mailType = getFolder.getMailType();
			if (this.mailType.equalsIgnoreCase(this.imap)) {
				imapFolder = (IMAPFolder) this.allFolder;
				imapFolder.open(1);
				msgs = imapFolder.search(search);
			} else {
				pop3Folder = (POP3Folder) this.allFolder;
				pop3Folder.open(1);
				msgs = pop3Folder.search(search);
			}
			if (msgs.length == 0) {
				return mails;
			}
			SaveEmailBean save = new SaveEmailBean();
			for (int i = msgs.length - 1; i >= 0; i--) {
				if ((isRead != null) && (isRead.equalsIgnoreCase("2"))) {
					if ((this.mailType.equalsIgnoreCase(this.imap))
							&& (!msgs[i].isSet(Flags.Flag.SEEN))) {
						EMail mail = save.saveMessage(msgs[i],
								this.account.getUserName(), this.mailType,
								this.allFolder);
						mails.add(mail);
					}
				} else {
					EMail mail = save.saveMessage(msgs[i],
							this.account.getUserName(), this.mailType,
							this.allFolder);
					mails.add(mail);
				}
			}
			return mails;
		} finally {
			if (this.mailType.equalsIgnoreCase(this.imap)) {
				if ((imapFolder != null) && (imapFolder.isOpen())) {
					imapFolder.forceClose();
				}
			} else if ((pop3Folder != null) && (pop3Folder.isOpen()))
				pop3Folder.close(true);
		}
	}

	public int getAllEMailsCount() throws Exception {
		IMAPFolder imapFolder = null;
		POP3Folder pop3Folder = null;
		int amount = 0;
		try {
			GetFolderBean getFolder = new GetFolderBean();
			this.allFolder = getFolder.getFolder(this.account);
			this.mailType = getFolder.getMailType();
			if (this.imap.equalsIgnoreCase(this.mailType)) {
				imapFolder = (IMAPFolder) this.allFolder;
				imapFolder.open(1);
				if (imapFolder == null) {
					return amount;
				}
				amount = imapFolder.getMessageCount();
			} else {
				pop3Folder = (POP3Folder) this.allFolder;
				pop3Folder.open(1);
				if (pop3Folder == null) {
					return amount;
				}
				amount = pop3Folder.getMessageCount();
				return amount;
			}
			return amount;
		} catch (Exception e) {
			throw new Exception("get folder failed", e);
		} finally {
			if (this.imap.equalsIgnoreCase(this.mailType)) {
				if ((imapFolder != null) && (imapFolder.isOpen())) {
					imapFolder.forceClose();
				}
			} else if ((pop3Folder != null) && (pop3Folder.isOpen()))
				pop3Folder.close(true);
		}
	}

	public EMail getPerMail(int index) throws Exception {
		IMAPFolder imapFolder = null;
		POP3Folder pop3Folder = null;
		Message[] msgs = (Message[]) null;
		EMail mail = null;
		try {
			GetFolderBean getFolder = new GetFolderBean();
			this.allFolder = getFolder.getFolder(this.account);
			this.mailType = getFolder.getMailType();
			if (this.mailType.equalsIgnoreCase(this.imap)) {
				imapFolder = (IMAPFolder) this.allFolder;
				imapFolder.open(2);
				msgs = imapFolder.getMessages(index, index);
			} else {
				pop3Folder = (POP3Folder) this.allFolder;
				pop3Folder.open(2);
				msgs = pop3Folder.getMessages(index, index);
			}
			SaveEmailBean savemail = new SaveEmailBean();
			if (msgs.length > 0) {
				for (int i = 0; i < msgs.length; i++) {
					mail = savemail.saveMail(msgs[i],
							this.account.getUserName(), this.mailType,
							this.allFolder);
				}
			}
			return mail;
		} finally {
			if (this.mailType.equalsIgnoreCase(this.imap))
				if ((imapFolder != null) && (imapFolder.isOpen())) {
					imapFolder.forceClose();
				} else if ((pop3Folder != null) && (pop3Folder.isOpen()))
					pop3Folder.close(true);
		}
	}

	public List<EMail> getEMailByUID(List<String> uids) throws Exception {
		IMAPFolder imapFolder = null;
		Message[] msgs = (Message[]) null;
		EMail mail = null;
		List<EMail> emails = new ArrayList<EMail>();
		try {
			GetFolderBean getFolder = new GetFolderBean();
			this.allFolder = getFolder.getFolder(this.account);
			this.mailType = getFolder.getMailType();
			if (this.mailType.equalsIgnoreCase(this.imap)) {
				imapFolder = (IMAPFolder) this.allFolder;
				imapFolder.open(2);
				long[] ids = { uids.size() };
				for (int i = 0; i < uids.size(); i++) {
					ids[i] = Long.parseLong((String) uids.get(i));
				}
				msgs = imapFolder.getMessagesByUID(ids);
			} else {
				return emails;
			}
			SaveEmailBean savemail = new SaveEmailBean();
			if (msgs.length > 0) {
				for (int i = 0; i < msgs.length; i++) {
					mail = savemail.saveMail(msgs[i],
							this.account.getUserName(), this.mailType,
							this.allFolder);
					emails.add(mail);
				}
			}
			return emails;
		} finally {
			if ((imapFolder != null) && (imapFolder.isOpen()))
				imapFolder.forceClose();
		}
	}

	public List<EMail> getAllEMails() throws Exception {
		IMAPFolder imapFolder = null;
		POP3Folder pop3Folder = null;
		Message[] msgs = (Message[]) null;
		try {
			List<EMail> allEmails = new ArrayList<EMail>();
			GetFolderBean getFolder = new GetFolderBean();
			this.allFolder = getFolder.getFolder(this.account);
			this.mailType = getFolder.getMailType();
			if (this.imap.equalsIgnoreCase(this.mailType)) {
				imapFolder = (IMAPFolder) this.allFolder;
				imapFolder.open(1);
				msgs = imapFolder.getMessages();
			} else {
				pop3Folder = (POP3Folder) this.allFolder;
				pop3Folder.open(1);
				msgs = pop3Folder.getMessages();
			}
			if ((msgs == null) || (msgs.length == 0)) {
				return allEmails;
			}
			SaveEmailBean savemail = new SaveEmailBean();
			for (int i = msgs.length - 1; i >= 0; i--) {
				EMail mail = null;
				mail = savemail.saveMessage(msgs[i],
						this.account.getUserName(), this.mailType,
						this.allFolder);
				allEmails.add(mail);
			}
			return allEmails;
		} finally {
			if ((imapFolder != null) && (imapFolder.isOpen())) {
				imapFolder.forceClose();
			}
			if ((pop3Folder != null) && (pop3Folder.isOpen()))
				pop3Folder.close(true);
		}
	}

	public List<EMail> getEMailByIndex(int start, int end) throws Exception {
		IMAPFolder imapFolder = null;
		POP3Folder pop3Folder = null;
		Message[] msgs = (Message[]) null;
		List<EMail> allEmails = new ArrayList<EMail>();
		try {
			GetFolderBean getFolder = new GetFolderBean();
			this.allFolder = getFolder.getFolder(this.account);
			imapFolder = (IMAPFolder) this.allFolder;
			this.mailType = getFolder.getMailType();
			if (this.mailType.equalsIgnoreCase(this.imap)) {
				imapFolder = (IMAPFolder) this.allFolder;
				imapFolder.open(1);
				msgs = imapFolder.getMessages(start, end);
			} else {
				pop3Folder = (POP3Folder) this.allFolder;
				pop3Folder.open(1);
				msgs = pop3Folder.getMessages(start, end);
			}
			if (msgs.length > 0) {
				SaveEmailBean savemail = new SaveEmailBean();
				for (int i = msgs.length - 1; i >= 0; i--) {
					EMail mail = savemail.saveMessage(msgs[i],
							this.account.getUserName(), this.mailType,
							this.allFolder);
					allEmails.add(mail);
				}
				return allEmails;
			}
			return allEmails;
		} finally {
			if (this.mailType.equalsIgnoreCase("imap")) {
				if ((imapFolder != null) && (imapFolder.isOpen())) {
					imapFolder.forceClose();
				}
			} else if ((pop3Folder != null) && (pop3Folder.isOpen()))
				pop3Folder.close(true);
		}
	}

	public int getUnreadEMailsCount() throws Exception {
		int unread = 0;
		GetFolderBean getFolder = new GetFolderBean();
		this.allFolder = getFolder.getFolder(this.account);
		IMAPFolder imapFolder = (IMAPFolder) this.allFolder;
		imapFolder.open(1);
		this.mailType = getFolder.getMailType();
		if ((this.mailType.equalsIgnoreCase(this.pop3))
				|| (this.mailType.equalsIgnoreCase(this.pop))) {
			return unread;
		}
		unread = imapFolder.getUnreadMessageCount();
		if (imapFolder.isOpen()) {
			imapFolder.forceClose();
		}
		return unread;
	}

	public List<EMail> getUnreaedEMails() throws Exception {
		IMAPFolder imapFolder = null;
		Message[] msgs = (Message[]) null;
		EMail mail = null;
		List<EMail> unreadEmails = new ArrayList<EMail>();
		try {
			GetFolderBean getFolder = new GetFolderBean();
			this.allFolder = getFolder.getFolder(this.account);
			this.mailType = getFolder.getMailType();
			if ((this.mailType.equalsIgnoreCase(this.pop3))
					|| (this.mailType.equalsIgnoreCase(this.pop))) {
				return unreadEmails;
			}
			imapFolder = (IMAPFolder) this.allFolder;
			imapFolder.open(1);
			msgs = imapFolder.getMessages();

			if (msgs.length == 0) {
				return unreadEmails;
			}

			SaveEmailBean savemail = new SaveEmailBean();
			for (int i = msgs.length - 1; i >= 0; i--) {
				if (!msgs[i].getFlags().contains(Flags.Flag.SEEN)) {
					mail = savemail.saveMessage(msgs[i],
							this.account.getUserName(), this.mailType,
							this.allFolder);
					unreadEmails.add(mail);
				}
			}
			return unreadEmails;
		} finally {
			if ((imapFolder != null) && (imapFolder.isOpen())) {
				imapFolder.forceClose();
			} else if ((this.allFolder != null) && (this.allFolder.isOpen()))
				this.allFolder.close(true);
		}
	}
}
